package com.sheep.jucdemo.part7.part7_5;

import java.util.Random;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @Date 2022/5/12 22:41
 * @Created by sheep
 */
public class Test7_5_3 {

    static class DelayedEle implements Delayed{
        // 延迟时间
        private final long delayTime;
        // 到期时间
        private final long expire;
        // 任务名称
        private String taskName;

        public DelayedEle(long delayTime, String taskName) {
            this.delayTime = delayTime;
            this.taskName = taskName;
            this.expire = System.currentTimeMillis() + delayTime;
        }

        /**
         * 剩余时间=到期时间-当前时间
         * @param unit
         * @return
         */
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        /**
         * 优先级队列里面的优先级规则
         * @param o
         * @return
         */
        @Override
        public int compareTo(Delayed o) {
            return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
        }

        @Override
        public String toString() {
            return "DelayedEle{" +
                    "delayTime=" + delayTime +
                    ", expire=" + expire +
                    ", taskName='" + taskName + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) {
        // 创建delay队列
        DelayQueue<DelayedEle> delayQueue = new DelayQueue<>();

        // 创建延迟任务
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            DelayedEle delayedEle = new DelayedEle(random.nextInt(500), "task:" + i);
            delayQueue.offer(delayedEle);
        }

        // 依次取出任务并打印
        DelayedEle ele = null;
        try {
            // 循环，如果想避免虚假唤醒，则不能把全部元素都打印出来
            for (;;){
                // 获取过期任务并打印
                while ((ele = delayQueue.take()) != null){
                    System.out.println(ele.toString());
                }
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

}
